package bd.com.escenic.flexilunch.util;

/**
 * $URL: http://flexilunch.googlecode.com/svn/trunk/core/src/main/java/bd/com/escenic/flexilunch/util/EnumUserType.java $
 * $Id: EnumUserType.java 15 2009-06-09 04:04:09Z shihab.uddin@gmail.com $
 * $Date: 2009-06-09 04:04:09 +0000 (Tue, 09 Jun 2009) $
 * $Author: shihab.uddin@gmail.com $
 * $Revision: 15 $
 */

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

/**
 * $Id: EnumUserType.java 15 2009-06-09 04:04:09Z shihab.uddin@gmail.com $.
 *
 * @author <a href="mailto:shihab.uddin@gmail.com">Shihab Uddin</a>
 * @version $Revision: 15 $
 */
abstract class EnumUserType<E extends Enum<E>> implements UserType {

  private static final int[] SQL_TYPES = {Types.VARCHAR};

  private Class<E> mEnumClass = null;

  EnumUserType(final Class<E> pEnumClass) {
    this.mEnumClass = pEnumClass;
  }

  @Override
  public int[] sqlTypes() {
    return SQL_TYPES;
  }

  @Override
  public Class returnedClass() {
    return mEnumClass;
  }

  @Override
  public Object nullSafeGet(final ResultSet pResultSet, final String[] pNames, Object pOwner)
      throws HibernateException, SQLException {
    String name = pResultSet.getString(pNames[0]);
    E result = null;
    if (!pResultSet.wasNull()) {
      result = Enum.valueOf(mEnumClass, name);
    }
    return result;
  }

  @Override
  public void nullSafeSet(final PreparedStatement pPreparedStatement, final Object pValue, final int pIndex)
      throws HibernateException, SQLException {
    if (pValue == null) {
      pPreparedStatement.setNull(pIndex, Types.VARCHAR);
    }
    else {
      pPreparedStatement.setString(pIndex, ((Enum) pValue).name());
    }
  }

  @Override
  public Object deepCopy(Object value) throws HibernateException {
    return value;
  }

  @Override
  public boolean isMutable() {
    return false;
  }

  @Override
  public Object assemble(final Serializable pCached, final Object pOwner) throws HibernateException {
    return pCached;
  }

  @Override
  public Serializable disassemble(final Object pValue) throws HibernateException {
    return (Serializable) pValue;
  }

  @Override
  public Object replace(final Object pOriginal, final Object pTarget, final Object pOwner) throws HibernateException {
    return pOriginal;
  }

  @Override
  public int hashCode(final Object pObject) throws HibernateException {
    return pObject.hashCode();
  }

  @Override
  public boolean equals(Object pX, Object pY) throws HibernateException {
    return pX == pY || (pX != null && pX.equals(pY));
  }
}
